package com.questionnaire.config.shiro;


import com.questionnaire.config.webConfig.SpringContextUtil;
import com.questionnaire.core.impl.JwtTokenManager;
import com.questionnaire.core.shiro.intercept.JwtAuthFilter;

import com.questionnaire.core.shiro.manager.MySessionManager;
import com.questionnaire.core.shiro.manager.ShiroDbRealm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.*;

/**
 * shiro权限管理的配置
 *
 * @author YSL
 * @date 2023年11月10日
 */
@Configuration
@ComponentScan(basePackages = "com.questionnaire.core")
public class ShiroConfig {
//    @Autowired
//    private JwtTokenManager jwtTokenManager;
    /**
     * 创建session对象
     */
    @Bean("simpleCookie")
    public SimpleCookie simpleCookie(){
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName("ShiroSession");
        return simpleCookie;
    }

    /**
     * 安全管理器
     */
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(this.shiroDbRealm());
        securityManager.setRememberMeManager(null);
        securityManager.setSessionManager(sessionManager());
        return securityManager;
    }

    /**
     * sessionManager 会话管理器
     */
    @Bean("sessionManager")
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new MySessionManager();
//        生效cookie
        sessionManager.setSessionIdCookieEnabled(true);
//        指定生成策略
        sessionManager.setSessionIdCookie(simpleCookie());
//        指定超时时间
        sessionManager.setGlobalSessionTimeout(3600000);
//        定时任务 刷新会话 没有配置 关闭它
        sessionManager.setSessionValidationSchedulerEnabled(false);
        return sessionManager;
    }

    /**
     * 项目自定义的Realm
     */
    @Bean
    public ShiroDbRealm shiroDbRealm() {
        return new ShiroDbRealm();
    }

    /**
     * 创建生命周期管理 除了他 bean的创建时间
     */
    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    /**
     * 开启 AOP注解的方式 鉴权
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
    @Bean("jwtTokenManager")
    public JwtTokenManager jwtTokenManager() {
        JwtTokenManager jwtTokenManager = new JwtTokenManager();
        return jwtTokenManager;
    }
    /**
     * Shiro的过滤器链
     */
    @Bean("shiroFilter")
    @DependsOn("jwtTokenManager")
    public ShiroFilterFactoryBean shiroFilter() {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager());
        /**
         * 默认的登陆访问url
         */
        shiroFilter.setLoginUrl("/login");
        /**
         * 登陆成功后跳转的url
         */
        shiroFilter.setSuccessUrl("/");
        /**
         * 没有权限跳转的url
         */
        shiroFilter.setUnauthorizedUrl("/global/error");

        /**
         * 自定义 过滤器
         */
        HashMap<String, Filter> myFilters = new HashMap<>();
        myFilters.put("user", new JwtAuthFilter(jwtTokenManager()));
        shiroFilter.setFilters(myFilters);
        /**
         * 配置shiro拦截器链
         *
         * anon  不需要认证
         * authc 需要认证
         * user  验证通过或RememberMe登录的都可以
         *
         * 当应用开启了rememberMe时,用户下次访问时可以是一个user,但不会是authc,因为authc是需要重新认证的
         *
         * 顺序从上到下,优先级依次降低
         *
         */
        Map<String, String> hashMap = new LinkedHashMap<>();

        hashMap.put("/login/**", "anon");
        //hashMap.put("/test/**", "anon");
        hashMap.put("/module/**", "anon");
        hashMap.put("/common/file/view/**", "anon");
        hashMap.put("/common/file/downfile/**", "anon");
        hashMap.put("/static/**", "anon");
        hashMap.put("/**", "user");
        shiroFilter.setFilterChainDefinitionMap(hashMap);
        return shiroFilter;
    }
}
